/* $RCSFile: PageLayout.aspx.cs $
 * Apache license v2 2011 by Christian Surieux
 * $Source: ?/AddonNice/PageModules/Pages/PageLayout.aspx.cs $
 * $log$
 * Revision 20 2010/08/09 10:51:22  christian.surieux
 *   Added Log comment to all .aspx .ascx .master files
 * Revision 19 2010/08/09 09:43:58  christian.surieux
 *   Added Log to cs sources files
 * Revision 6 2010/08/06 19:56:26  christian.surieux
 *   Added Log to All cs files
 */

using System;
using System.Collections;
using System.Collections.Generic;
using System.Data.SqlClient;
using System.Security.Principal;
using System.Globalization;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;

using AddonNice.Core;
using AddonNice.Helpers;
using AddonNice.Configuration;
using AddonNice.Security;
using AddonNice.Settings;
using AddonNice.Settings.Cache;
using AddonNice.UI;
using AddonNice.Diagnostics;
using AddonNice.CRMWrapper;
using Trace2    =   System.Diagnostics.Trace;

using Telerik.Web.UI;

namespace AddonNice.PageModules.Pages
{

	#region TraceSwitch for PageLayout
	public class PageLayoutTrace
	{
		static public ADNTraceSwitch	Sw	=	new ADNTraceSwitch("PageLayoutTrace","Trace Switch for Page Layout");
	}
	#endregion TraceSwitch for PageLayout

    public partial class PageLayout : EditItemPage
	{
		PagesDB pagesDB		                =	new PagesDB();
        ModulesDB modDB                     =   new ModulesDB();

        const string strSessionDockState    =   "PageLayout_DockStates";
        const string strContentPane         =   "ContentPane";
        const string strLeftPane            =   "LeftPane";
        const string strRightPane           =   "RightPane";

        #region Docking properties

        bool SessionDataOk
        {
            get
            {
                return Session[strSessionDockState] != null;
            }
        }
       
        void ClearSessionData()
        {
            Session.Remove(strSessionDockState);
        }

        List<DockState> _currentDockStates  = null;
        private List<DockState> CurrentDockStates
		{
			get
			{
				//Store the info about the added docks in the session. For real life
				// applications we recommend using database or other storage medium 
				// for persisting this information.
                bool IsDockNull             =   ( _currentDockStates == null);
                if (IsDockNull)
                {
                    if (PageLayoutTrace.Sw.TraceVerbose)
                        Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]PageLayout CurrentDockStates Get is null : {0}", IsDockNull),PageLayoutTrace.Sw.Info);
                    _currentDockStates  =   (List<DockState>)Session[strSessionDockState];
                }
				return _currentDockStates;
			}
			set
			{
                if (PageLayoutTrace.Sw.TraceVerbose)
                    Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]PageLayout CurrentDockStates Set, Count: {0}", value.Count),PageLayoutTrace.Sw.Info);
                _currentDockStates          =   value;
                Session[strSessionDockState]=   value;
			}
        }

        #endregion 

        #region ADNPage overrides
        
        /// <summary>
        /// Only difference with ADNPage.SaveUrlReferrer: we accept pages from the logon url to be able to change their properties
        /// </summary>
        public override void SaveUrlReferrer()
        {
            if (Request.UrlReferrer == null)
            {
                if (PageTraceSwitch.Sw.TraceVerbose ||PageLayoutTrace.Sw.TraceVerbose)
                    Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]PageLayout SaveUrlReferrer UrlReferrer Null for type: {0}, PageId: {1}.", this,PageID), (PageTraceSwitch.Sw.TraceVerbose)? PageTraceSwitch.Sw.Info: PageLayoutTrace.Sw.Info);
                return;
            }
            string str          =   Request.UrlReferrer.ToString();
            string modulePath   =   Config.ModulesPath.TrimStart(new char[]{'~','/'});
            if ( (str == string.Empty ) || 
                ( str.IndexOf(modulePath,StringComparison.InvariantCultureIgnoreCase) != -1 ) ||
                ( str.IndexOf(Config.ModuleSettingsPage,StringComparison.InvariantCultureIgnoreCase) != -1 ) ||
                ( str.IndexOf(Config.PageLayoutPage,StringComparison.InvariantCultureIgnoreCase) != -1 ) ||
                ( str.IndexOf(Config.ModulePropertyPage,StringComparison.InvariantCultureIgnoreCase) != -1 ) ||
                //( str.IndexOf(Config.PortalLogonDirectory+"/",StringComparison.InvariantCultureIgnoreCase) != -1 ) || // here we allow it
                ( str.IndexOf(Config.ModuleCustomPropertyPage,StringComparison.InvariantCultureIgnoreCase) != -1 ) )
            {
                if (PageLayoutTrace.Sw.TraceVerbose)
                    Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]PageLayout SaveUrlReferrer UrlReferrer not stored, contains propertyPage: '{0}', PageId: {1}.", str,PageID), PageLayoutTrace.Sw.Info);
                return;
            }
            if (PageTraceSwitch.Sw.TraceVerbose ||PageLayoutTrace.Sw.TraceVerbose)
                Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]PageLayout SaveUrlReferrer UrlReferrer: '{0}'.",str), (PageTraceSwitch.Sw.TraceVerbose)? PageTraceSwitch.Sw.Info: PageLayoutTrace.Sw.Info);
            UrlReferrer     =   str;
            ReturnUrl       =   str;
        }

        #endregion ADNPage overrides

        /// <summary>
		/// The Page_Load server event handler on this page is used
		/// to populate a tab's layout settings on the page
		/// </summary>
		private void Page_Load(object sender, EventArgs e)
		{
            if (PageTraceSwitch.Sw.TraceVerbose || PageLayoutTrace.Sw.TraceVerbose)
                Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]PageLayout Page_Load BEG IsPostBack: {0}, IsInAsyncPostBack: {1}", 
                    IsPostBack,IsInAsyncPostBack),(PageTraceSwitch.Sw.TraceVerbose) ? PageTraceSwitch.Sw.Info:PageLayoutTrace.Sw.Info);

            // The 'autopostbacking' controls are ajaxified
            AddAjaxSetting(ClbFlags,ClbFlags);
            AddAjaxSetting(tabName,tabName);
			AddAjaxSetting(authRoles,authRoles);
			AddAjaxSetting(DDLPageImage,DDLPageImage);
			AddAjaxSetting(parentPage,parentPage);
			AddAjaxSetting(parentPage,lblErrorNotAllowed);
			
            // Width textboxes
            AddAjaxSetting(TbLWidth,Panel1);
            AddAjaxSetting(TbCWidth,Panel1);
            AddAjaxSetting(TbRWidth,Panel1);
            
            // Ajaxify all existing docks
            for (int i = 0; i < RadDockLayout1.Controls.Count; i++)
            {
                Control ctrl    =   RadDockLayout1.Controls[i];
                if ( !(ctrl is RadDock ) )
                    continue;
                RadDock dock    =   (RadDock)ctrl;
                AddAjaxSetting(dock,Panel1);
            }

            // If first visit to the page, update all entries
			if (!IsPostBack) 
			{
				BindData();
				RadMultiPage1.SelectedIndex	        =   0;
				RadTabStrip1.SelectedIndex		    =   0;
                previewBtn.OnClientClick            =    GetPopupCommand();
                previewBtn.Attributes.Add("href",HttpUrlBuilder.BuildUrl(PageID));
                // Don't change order for pages from common portal
                if (portalSettings.ActivePageSettings.PortalID == StStr.CommonPortalID)
                {
                    parentPage.Enabled  =   false;
                }
			}
            if (PageTraceSwitch.Sw.TraceVerbose || PageLayoutTrace.Sw.TraceVerbose)
                Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]PageLayout Page_Load END IsPostBack: {0}", IsPostBack),
                    (PageTraceSwitch.Sw.TraceVerbose) ? PageTraceSwitch.Sw.Info:PageLayoutTrace.Sw.Info);
		}

		/// <summary>
		/// The BindData helper method is used to update the tab's
		/// layout panes with the current configuration information
		/// </summary>
		private void BindData() 
		{
            if (PageLayoutTrace.Sw.TraceVerbose)
                Trace2.WriteLine("[V]PageLayout BindData BEG.",PageLayoutTrace.Sw.Info);
            EditTable.DataBind();

			PageSettings tab			        =   portalSettings.ActivePageSettings;
            // Populate Tab Names, etc.
            LblTabID.Text                       =   tab.PageID.ToString();
            tabName.Text				        =   tab.PageName;
            LblPageUrl.Text                     =   tab.PageUrlName;
            // Fill flags
            for (int i=1 ; i <= (int)ADNPageFlags.OnlyAuthenticated; i <<= 1 )
            {
                ADNPageFlags f                  =   (ADNPageFlags)i;
                ListItem fit                    =   new ListItem(f.ToString(),((int)f).ToString());
                if ( (tab.Flags & f) == f )
                    fit.Selected                =   true;
                ClbFlags.Items.Add(fit);
            }
            if (PageLayoutTrace.Sw.TraceVerbose)
                Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]PageLayout BindData PageName: {0}, Width[0]: {1}, Width[1]: {2}, Width[2]: {3}", 
                    new object[]{tab.PageName,tab.Width[0],tab.Width[1],tab.Width[2]}),PageLayoutTrace.Sw.Info);
            // Panes size
            int val                             =   tab.Width[0];
            int tot                             =   ( Math.Abs(tab.Width[0]) + Math.Abs(tab.Width[1]) + Math.Abs(tab.Width[2]) );
            bool isPurcent                      =   (tot == 0 ) || (val < 0 ) || (tab.Width[1] < 0 ) || (tab.Width[2] < 0 );
            if (PageLayoutTrace.Sw.TraceVerbose)
                Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]PageLayout BindData PageName: {0}, isPurcent: {1}", 
                    tab.PageName,isPurcent),PageLayoutTrace.Sw.Info);
            // check sum = 100 %
            if ( isPurcent )
            {
                if ( tot != 100 )
                {
                    if (PageLayoutTrace.Sw.TraceVerbose)
                        Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]PageLayout BindData PageName: {0}, total: {1}", 
                            tab.PageName,tot),PageLayoutTrace.Sw.Info);
                    tab.Width[0] = tab.Width[2] =   -33;
                    tab.Width[1]                =   -34;            
                }
                val                             =   tab.Width[0];
            }
            // Dimension the modules panes
            RadComboUnit.SelectedValue          =   (isPurcent) ? "1":"0";
            TbLWidth.Value                      =   Math.Abs(val);
            // we must convert to %
            if ( isPurcent && ( val != 0 ) ) // zero in % is Nok
                RadPane1.Width                  =   new Unit(Math.Abs(val),UnitType.Percentage);
            else RadPane1.Width                 =   new Unit(Math.Abs(val), UnitType.Pixel);
            val                                 =   tab.Width[1];
            TbCWidth.Value                      =   Math.Abs(val);
            if (isPurcent && ( val != 0 ) ) // zero in % is Nok
                RadPane2.Width                  =   new Unit(Math.Abs(val),UnitType.Percentage);
            else RadPane2.Width                 =   new Unit(Math.Abs(val), UnitType.Pixel);
            RadComboUnit.SelectedValue          =   (isPurcent) ? "1":"0";
            val                                 =   tab.Width[2];
            TbRWidth.Value                      =   Math.Abs(val);
            if (isPurcent && ( val != 0 ) ) // zero in % is Nok
                RadPane3.Width                  =   new Unit(Math.Abs(val),UnitType.Percentage);
            else RadPane3.Width                 =   new Unit(Math.Abs(val), UnitType.Pixel);
            
            // Populate the "ParentPage" Data
            parentPage.SelectedTreeViewValue    =   tab.ParentPageID.ToString();
            parentPage.DataBind();
            if (PageLayoutTrace.Sw.TraceVerbose)
                Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]PageLayout BindData after DataBind parentPage.Text : [{0}].", parentPage.Text),PageLayoutTrace.Sw.Info);

            // Populate the DDLPageImage and select existing
            if (PageLayoutTrace.Sw.TraceVerbose)
                Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]PageLayout BindData before GetImageMenu PageImage:[{0}]",tab.PageImage),PageLayoutTrace.Sw.Info);
            Hashtable htb                       =   portalSettings.GetImageMenu();
            DDLPageImage.DataSource             =   htb;
            DDLPageImage.DataBind();
            RadComboBoxItem it                  =   null;
            if (tab.PageImage != string.Empty)
            {
                it                              =   DDLPageImage.FindItemByValue(tab.PageImage.ToLower(CultureInfo.InvariantCulture));
                if ( it != null )
                    it.Selected                 =   true;
            }
            if ( it == null )
                DDLPageImage.SelectedIndex      =   0;


			fillRolesList(authRoles, tab.AuthorizedRoles);
            moduleType.DataBind();

            RadComboBoxItem lsti                =   new RadComboBoxItem( LocalizeHelper.Localize("AM_MODULEVISIBLETO_ALLUSERS"),DBAllUser2);
            lsti.Selected                       =   true;
            viewPermissions.Items.Add(lsti);
            lsti                                =   new RadComboBoxItem ( LocalizeHelper.Localize("AM_MODULEVISIBLETO_ADMINSROLE"),DBAdmin2);
            viewPermissions.Items.Add(lsti);
            if (PageLayoutTrace.Sw.TraceVerbose)
                Trace2.WriteLine("[V]PageLayout BindData END.",PageLayoutTrace.Sw.Info);
        }

        void SetReturnPage()
        {
            // redirect back to the admin page
            // use returnPageID from QueryString
            string retPage      =   Request.QueryString[StStr.returnPageID];
            if (!string.IsNullOrEmpty(retPage)) // user is returned to the calling tab.
            {
                //to select this Page
                string strarg   =   string.Format("{0}={1}", StStr.selectedItem, PageID);
                UrlReferrer     =   HttpUrlBuilder.BuildUrlWithCustomAttributes(int.Parse(retPage), strarg);
            }
            else // user is returned to updated tab
                UrlReferrer     =   HttpUrlBuilder.BuildUrl(PageID);
        }

        void PageLayout_Cancel(object sender, EventArgs e)
        {
            SetReturnPage();
        }

        /// <summary>
		/// Save the current page settings to the database and
		/// then redirect back to the calling page. 
		/// </summary>
        void PageLayout_Update(object sender, AddonNice.UI.ADNPageEventArgs e)
        {
            if (PageLayoutTrace.Sw.TraceVerbose)
                Trace2.WriteLine("[V]PageLayout PageLayout_Update BEG.",PageLayoutTrace.Sw.Info);
            try
            {
                // Update custom settings in the database
                EditTable.UpdateControls();
                //Invalidate any page cache
                ResetSettings(true);
                // Flush all tab navigation cache keys. Very important for recovery the changes
                // made in all languages and not get a error if user change the tab parent.
                CurrentCache.RemoveGlobalPagesCacheKey();
                CurrentCache.RemoveAll(StStr.PageNavigationSettings);
                CurrentCache.RemoveAll(StStr.AuthorizedPageStripDetail);
			    portalSettings.ReloadPortal(true);
                portalSettings.ReloadMenus();
                SetReturnPage();
            }
            catch(Exception ex)
            {
                if (PageLayoutTrace.Sw.TraceError)
                    Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[E]PageLayout PageLayout_Update ex : {10}", ex),PageLayoutTrace.Sw.Info);
                throw;
            }
            if (PageLayoutTrace.Sw.TraceVerbose)
                Trace2.WriteLine("[V]PageLayout PageLayout_Update END.",PageLayoutTrace.Sw.Info);
		}

		/// <summary>
		/// Extracts roles from a checkedListBox
		/// </summary>
		public string ExtractRoles(CheckBoxList box)
		{
			string authorizedRoles	    =   string.Empty;

			StringBuilder sb = new StringBuilder();
			foreach (ListItem item in box.Items)
			{
				if (item.Selected)
				{
					string str          =   item.Text;
					if (str == CRMAllUsers)
						str             =   DBAllUser;
					else if ( str == CRMAdmin )
						str             =   DBAdmin;
					sb.AppendFormat("{0};", str);
				}
			}
			return sb.ToString();
		}

		/// <summary>
		/// Installs roles in checkedListBox from db values
		/// </summary>
		public void fillRolesList(CheckBoxList authRoles, string AuthorizedRoles)
		{
			// Clear existing items in checkboxlist
            authRoles.Items.Clear();

            ListItem allItem			=   new ListItem();
            allItem.Text				=   CRMAllUsers;

            if (AuthorizedRoles.LastIndexOf(DBAllUser) > -1)
            {
                allItem.Selected		=   true;
            }

            authRoles.Items.Add(allItem);

            // get the CRM Roles
            string[] CrmRoles			=   PortalSecurity.GetCRMRoles();
            foreach (string cr in CrmRoles)
            {
                ListItem lItem			=   new ListItem();
                lItem.Text				=   cr;
                authRoles.Items.Add(lItem);
            }

            //Splits up the role string and use array 
			AuthorizedRoles.TrimEnd(new char[] { ';' });
            string[] arrModuleRoles     =   AuthorizedRoles.Split(';');
            int roleCount               =   arrModuleRoles.GetUpperBound(0);

            // We transform the internal Admin in CRM admin to check ok later
            for (int i = 0; i <= roleCount; i++)
            {
                if (arrModuleRoles[i] == DBAdmin)
                    arrModuleRoles[i]   =   CRMAdmin;
				else if (arrModuleRoles[i] == DBAllUser )
					arrModuleRoles[i]   =   CRMAllUsers;
            }
            // Cycle every role and select it if needed
            foreach (ListItem ls in authRoles.Items)
            {
                for (int i = 0; i <= roleCount; i++)
                {
                    if (arrModuleRoles[i].ToLower(CultureInfo.InvariantCulture) == ls.Text.ToLower(CultureInfo.InvariantCulture))
                        ls.Selected     =   true;
                }
            }
		}

		/// <summary>
		/// The SavePageData helper method is used to persist the
		/// current tab settings to the database.
		/// </summary>
		private void SavePageData() 
		{
            if (PageLayoutTrace.Sw.TraceVerbose)
                Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]PageLayout SavePageData BEG tabName.Text: {0}", tabName.Text),PageLayoutTrace.Sw.Info);
			// Construct Authorized User Roles string
			string authorizedRoles	    =   ExtractRoles(authRoles);
			// update Page info in the database
            try
            {
                portalSettings.FlushSkinImageMenuCache();
                int w0                  =   (TbLWidth.Value.HasValue) ? (int)TbLWidth.Value.Value:0;
                int w1                  =   (TbCWidth.Value.HasValue) ? (int)TbCWidth.Value.Value:0;
                int w2                  =   (TbRWidth.Value.HasValue) ? (int)TbRWidth.Value.Value:0;
                // purcentages are negative
                if (RadComboUnit.SelectedValue == "1")
                {
                    // check sum = 100 %
                    int tot             =   w0+w1+w2;
                    if ( tot != 100 )
                    {
                        if ( TbLWidth.Value.HasValue  )
                            adjustTotal(TbLWidth,RadPane1,ref w0,w1,w2);
                        else if ( TbCWidth.Value.HasValue  )
                            adjustTotal(TbCWidth,RadPane2,ref w1,w0,w2);
                        else if ( TbRWidth.Value.HasValue  )
                            adjustTotal(TbRWidth,RadPane3,ref w2,w0,w1);
                    }
                    w0                  =   -w0;
                    w1                  =   -w1;
                    w2                  =   -w2;
                    // Equally spaced
                    if ( ( (w0 == 33) && (w1 == 34) )
                        || ( (w0 == 33) && (w1 == 33) )
                        || ( (w1 == 34) && (w1 == 33) ) )
                        w0=w1=w2=0;
                    }
                if (PageLayoutTrace.Sw.TraceVerbose)
                    Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]PageLayout SavePageData w0: {0}, w1: {1}, w2: {2}",w0,w1,w2),PageLayoutTrace.Sw.Info);
				if (PageLayoutTrace.Sw.TraceVerbose)
                    Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]PageLayout SavePageData before update module in DB parentPage.SelectedValue: {0}, parentPage.SelectedItem.Value: {1}", 
                        parentPage.SelectedValue,parentPage.SelectedItem.Value),PageLayoutTrace.Sw.Info);
                int pgId    =   (string.IsNullOrEmpty(parentPage.SelectedValue)) ? 0:Int32.Parse(parentPage.SelectedValue);
                pagesDB.UpdatePage(portalSettings.PortalID, PageID, pgId, tabName.Text,DDLPageImage.SelectedItem.Value, portalSettings.ActivePageSettings.PageOrder, 
                    3,w0,w1,w2,0,0,authorizedRoles);
            }
            catch (Exception ex)
            {
                if (PageLayoutTrace.Sw.TraceError)
                    Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[E]PageLayout SavePageData, ex : {10}", ex),PageLayoutTrace.Sw.Info);
                throw;
            }			
            if (PageLayoutTrace.Sw.TraceVerbose)
                Trace2.WriteLine("[V]PageLayout SavePageData END.",PageLayoutTrace.Sw.Info);
		}

        /// <summary>
		/// This method override the security cookie to allow 
		/// accessing the property pages of selected module in page.
		/// </summary>
		private void SetSecurityAccess(ArrayList AllItems) 
		{
			Guid guid;

			StringBuilder sb	=	new StringBuilder();
			foreach (ModuleItem li in AllItems) 
			{
				guid			=   modDB.GetModuleGuid(li.ID);
				if ( guid != Guid.Empty ) 
					sb.AppendFormat("{0}@",guid.ToString().ToUpper());
			}

			string guidsInUse	=   sb.ToString();

			HttpCookie cookie	=   new HttpCookie (StStr.strSecurityCookieName, guidsInUse);
			DateTime time		=   DateTime.Now;
			TimeSpan span		=   new TimeSpan (0, 2, 0, 0, 0); // 120 minutes to expire
			cookie.Expires		=   time.Add (span);
			base.Response.AppendCookie (cookie);
        }

        
        #region event handlers 
		/// <summary>
		/// Trigger used by SettinTable when a control needs to be updated
        /// Origin from this call is in OnUpdate
		/// </summary>
        private void EditTable_UpdateControl(object sender, SettingsTableItemEventArgs e)
		{
            if (SettingsTraceSwitch.Sw.TraceVerbose)
                Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]PageLayout EditTable_UpdateControl e.CurrentItem.EditControl.ID: {0}, e.CurrentItem.Value: [{1}]", e.CurrentItem.EditControl.ID, e.CurrentItem.Value),SettingsTraceSwitch.Sw.Info);
            pagesDB.UpdatePageSettings(PageID, e.CurrentItem.EditControl.ID, e.CurrentItem.Value);
        }

        void parentPage_SelectedIndexChanged(object o, RadComboBoxSelectedIndexChangedEventArgs e)
        {
            if (PageLayoutTrace.Sw.TraceVerbose)
                Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]PageLayout parentPage_SelectedIndexChanged BEG OldValue: {0}, Value: {1}.",e.OldValue,e.Value),PageLayoutTrace.Sw.Info);
            // TBD: Missing check on page validity
            PageSettings_Change(o,e); 
        }

        void DDLPageImage_SelectedIndexChanged(object o, RadComboBoxSelectedIndexChangedEventArgs e)
        {
            if (PageLayoutTrace.Sw.TraceVerbose)
                Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]PageLayout DDLPageImage_SelectedIndexChanged BEG OldValue: {0}, Value: {1}.",e.OldValue,e.Value),PageLayoutTrace.Sw.Info);
            PageSettings_Change(o,e); 
        }

        /// <summary>
		/// The PageSettings_Change server event handler on this page is
		/// invoked any time the tab name or access security settings
		/// change.  The event handler in turn calls the "SavePageData"
		/// helper method to ensure that these changes are persisted
		/// to the portal configuration file.
		/// </summary>
		private void PageSettings_Change(Object sender, EventArgs e) 
		{
            if (PageLayoutTrace.Sw.TraceVerbose)
                Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]PageLayout PageSettings_Change BEG sender: {0}", ((Control)sender).ID),PageLayoutTrace.Sw.Info);
			// Ensure that settings are saved
			SavePageData();
            if (PageLayoutTrace.Sw.TraceVerbose)
                Trace2.WriteLine("[V]PageLayout PageSettings_Change END.",PageLayoutTrace.Sw.Info);
		}

        void ClbFlags_TextChanged(object sender,EventArgs e)
        {
            if (PageLayoutTrace.Sw.TraceVerbose)
                Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]PageLayout ClbFlags_TextChanged BEG sender: {0}", ((Control)sender).ID),PageLayoutTrace.Sw.Info);
            string url              =   LblPageUrl.Text.Trim();
            int Flag                =   0;
            foreach (ListItem it in ClbFlags.Items )
            {
                if ( it.Selected )
                    Flag    |=  int.Parse(it.Value);
            }
            pagesDB.UpdateUrlAndLayout(PageID,url,Flag);
            if (PageLayoutTrace.Sw.TraceVerbose)
                Trace2.WriteLine("[V]PageLayout ClbFlags_TextChanged END.",PageLayoutTrace.Sw.Info);
        }

        /// <summary>
        /// Keep a 100% total width for % values
        /// </summary>
        bool adjustTotal(RadNumericTextBox tb,RadPane pn,ref int w0,int w1,int w2)
        {
            if (PageLayoutTrace.Sw.TraceVerbose)
                Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]PageLayout adjustTotal BEG w0: {0}, w1: {1}, w2: {2}",w0,w1,w2),PageLayoutTrace.Sw.Info);
            int tot             =   w0+w1+w2;
            bool ajusted        =   false;
            while (( tot != 100 ) && ( w0 > 0 ))
            {
                if ( tot < 100 )
                     w0++;
                else w0--;
                tot             =   w0 + w1 + w2;
                ajusted         =   true;
            }
            if ( ajusted )
            {
                tb.Value        =   (double)w0;
                pn.Width        =   new Unit((double)w0,UnitType.Percentage);
            }
            if (PageLayoutTrace.Sw.TraceVerbose)
                Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]PageLayout adjustTotal END ajusted: {0}",ajusted),PageLayoutTrace.Sw.Info);
            return ajusted;
        }

        // Save new panels sizes
        void TbWidth_TextChanged(object sender, EventArgs e)
        {
            if (PageLayoutTrace.Sw.TraceVerbose)
                Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]PageLayout TbWidth_TextChanged BEG sender: {0}", ((RadNumericTextBox)sender).ID),PageLayoutTrace.Sw.Info);

            // update Page info in the database
            try
            {
                portalSettings.FlushSkinImageMenuCache();
                int w0  =   (TbLWidth.Value.HasValue) ? (int)TbLWidth.Value.Value:0;
                int w1  =   (TbCWidth.Value.HasValue) ? (int)TbCWidth.Value.Value:0;
                int w2  =   (TbRWidth.Value.HasValue) ? (int)TbRWidth.Value.Value:0;
                // purcentages are negative
                if (RadComboUnit.SelectedValue == "1")
                {
                    // check sum = 100 %
                    int tot                         =   w0+w1+w2;
                    if ( tot != 100 )
                    {
                        if ( sender is RadNumericTextBox )
                        {
                            RadNumericTextBox tb    =   (RadNumericTextBox )sender;
                            if ( tb == TbLWidth )
                                adjustTotal(tb,RadPane1,ref w0,w1,w2);
                            else if ( tb == TbCWidth )
                                adjustTotal(tb,RadPane2,ref w1,w0,w2);
                            else if ( tb == TbRWidth )
                                adjustTotal(tb,RadPane3,ref w2,w0,w1);
                        }
                    }
                    w0= -w0;
                    w1= -w1;
                    w2= -w2;
                }
                if (PageLayoutTrace.Sw.TraceVerbose)
                    Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]PageLayout TbWidth_TextChanged w0: {0}, w1: {1}, w2: {2}",w0,w1,w2),PageLayoutTrace.Sw.Info);
                pagesDB.UpdatePagePanes(PageID,3,w0,w1,w2,0,0);
            }
            catch (Exception ex)
            {
                if (PageLayoutTrace.Sw.TraceError)
                    Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[E]PageLayout TbWidth_TextChanged ex : {0}", ex),PageLayoutTrace.Sw.Info);
                throw;
            }			
            if (PageLayoutTrace.Sw.TraceVerbose)
                Trace2.WriteLine("[V]PageLayout TbWidth_TextChanged END.",PageLayoutTrace.Sw.Info);
        }

        #endregion event handlers

        #region dock methods

        /// <summary>
		/// The AddModuleBtn_Click server event handler 
		/// on this page is used to add a new portal module into the tab
		/// </summary>
		void AddModuleBtn_Click(object sender, ImageClickEventArgs e)
		{
            if (PageLayoutTrace.Sw.TraceVerbose)
                Trace2.WriteLine("[V]PageLayout AddModuleBtn_Click BEG.",PageLayoutTrace.Sw.Info);
            if (string.IsNullOrEmpty(moduleTitle.Text))
            {
                if (PageLayoutTrace.Sw.TraceVerbose)
                    Trace2.WriteLine("[V]PageLayout AddModuleBtn_Click IsValid False.",PageLayoutTrace.Sw.Info);
                return;
            }
            
            if (string.IsNullOrEmpty(moduleType.SelectedValue))
            {
                if (PageLayoutTrace.Sw.TraceVerbose)
                    Trace2.WriteLine("[V]PageLayout AddModuleBtn_Click IsValid False.",PageLayoutTrace.Sw.Info);
                return;
            }
            // All new modules go to the end of the contentpane
            ModuleItem m			=	new ModuleItem();
            m.Title					=	moduleTitle.Text;
            m.ModuleDefID			=	Int32.Parse(moduleType.SelectedValue);
            m.Order					=	999;
			string pane				=	paneLocation.SelectedItem.Value.ToString();
            // save to database
            try
            {
                // The new module inherits security from current page current module (current ModuleID) 
                // so who can edit the tab properties/content can edit the module properties/content (except view that remains =)
                m.ID				=   modDB.AddModule(PageID, m.Order,0, pane, m.Title, m.ModuleDefID, 0,
                                                        DBAdmin2, viewPermissions.SelectedItem.Value.ToString(),
                                                        DBAdmin2, DBAdmin2,
                                                        DBAdmin2, DBAdmin2,
                                                        DBAdmin2, false, false);
            }
            catch (Exception ex)
            {
                if (PageLayoutTrace.Sw.TraceError)
                    Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[E]PageLayout Exception inserting module: {0), ex : {1}", moduleTitle.Text, ex),PageLayoutTrace.Sw.Info);
                throw;
            }
			portalSettings.ReloadPortal(true);
            // Create the Dock
            RadDockZone zn          =   RadDockZone2;
            switch(paneLocation.SelectedValue)
            {
                case strLeftPane:
                    zn              =   RadDockZone1;
                    break;
                case strContentPane:
                    zn              =   RadDockZone2;
                    break;
                case strRightPane:
                    zn              =   RadDockZone3;
                    break;
            }
            AddNewDock(m,zn,false);
            if (PageLayoutTrace.Sw.TraceVerbose)
                Trace2.WriteLine("[V]PageLayout AddModuleBtn_Click END.",PageLayoutTrace.Sw.Info);
        }

        /// <summary>
        /// Visibility changed from one module in a dock
        /// </summary>
        void Ddl_SelectedIndexChanged(object sender, RadComboBoxSelectedIndexChangedEventArgs e)
        {
            if (PageLayoutTrace.Sw.TraceVerbose)
                Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]PageLayout Ddl_SelectedIndexChanged BEG sender: {0}", sender),PageLayoutTrace.Sw.Info);
            RadComboBox Ddl     =   (RadComboBox)sender;
            string strModuleID  =   Ddl.ID.Substring(4);
            int idx             =   strModuleID.IndexOf("_Perm");
            strModuleID         =   strModuleID.Substring(0,idx);
            if (PageLayoutTrace.Sw.TraceVerbose)
                Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]PageLayout Ddl_SelectedIndexChanged strModuleID: {0}", strModuleID),PageLayoutTrace.Sw.Info);
            try
            {
                int mID         =   int.Parse(strModuleID);
                string selRole  =   Ddl.SelectedValue;
                if (PageLayoutTrace.Sw.TraceVerbose)
                    Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]PageLayout Ddl_SelectedIndexChanged selRole: {0}", selRole),PageLayoutTrace.Sw.Info);
                modDB.UpdateModuleViewRole(mID, selRole + ";");
            }
            catch (Exception ex)
            {
                if (PageLayoutTrace.Sw.TraceError )
                    Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]PageLayout Ddl_SelectedIndexChanged ex: {0}",ex),PageLayoutTrace.Sw.Info);
                throw;
            }
            if (PageLayoutTrace.Sw.TraceVerbose)
                Trace2.WriteLine( "[V]PageLayout Ddl_SelectedIndexChanged END.",PageLayoutTrace.Sw.Info);
        }

        /// <summary>
        /// Handler for radDocks commands
        /// </summary>
        void dock_Command(object sender, DockCommandEventArgs e)
        {
            if (PageLayoutTrace.Sw.TraceVerbose)
                Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]PageLayout dock_Command Command.Name: {0}", e.Command.Name),PageLayoutTrace.Sw.Info);
            if (e.Command.Name == "Edit")
            {
                try
                {
                    int mid			=   Int32.Parse(((RadDock)sender).UniqueName);
                    if (PortalSecurity.IsUserInRoles(PortalSecurity.GetPropertiesPermissions(mid)))
                    {
                        // Redirect to module settings page
                        string url  =   HttpUrlBuilder.BuildUrl(Config.ModulesPath + "/" + Config.ModuleSettingsPage, PageID, mid);
                        if (PageLayoutTrace.Sw.TraceVerbose)
                            Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]PageLayout dock_Command Edit url: {0}", url),PageLayoutTrace.Sw.Info);
                        Redirect(url,true);
                        //Response.Redirect(url);
                        return;
                    }
                    msgError.Text   = LocalizeHelper.Localize("AM_NO_RIGHTS","You have no privileges for this action");
                    return;
                }
                catch (System.Threading.ThreadAbortException)
                {
                    throw;
                }
                catch (Exception ex)
                {
                    if (PageLayoutTrace.Sw.TraceError)
                        Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[E]PageLayout dock_Command ex: {0}", ex),PageLayoutTrace.Sw.Info);
                    throw;
                }
            }
            else if (e.Command.Name == "Close")
            {
                string script   =   string.Format(@"function _removeDock() {{
	                Sys.Application.remove_load(_removeDock);
	                $find('{0}').undock();
	                $get('{1}').appendChild($get('{0}'));
	                $find('{0}').doPostBack('DockPositionChanged');}};
                    Sys.Application.add_load(_removeDock);",((RadDock)sender).ClientID,Panel2.ClientID);
                if (PageLayoutTrace.Sw.TraceVerbose)
                    Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]PageLayout dock_Command Close script: {0}", script),PageLayoutTrace.Sw.Info);
                ScriptManager.RegisterStartupScript(Panel2,GetType(),"RemoveDock",script,true);
                int mid			= Int32.Parse(((RadDock)sender).UniqueName);
                if (PageLayoutTrace.Sw.TraceVerbose)
                    Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]PageLayout dock_Command Close ModuleID: {0}", mid),PageLayoutTrace.Sw.Info);
				if ( mid > -1 ) 
				{
                    string strdelperm   =   PortalSecurity.GetDeleteModulePermissions(mid);
                    if (PageLayoutTrace.Sw.TraceVerbose)
                        Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]PageLayout dock_Command DeletePermissions: {0}", strdelperm),PageLayoutTrace.Sw.Info);
					// Add role control for delete module
                    if (PortalSecurity.IsUserInRoles(strdelperm))
					{
						// must delete from database too
						new ModulesDB().DeleteModule(mid,Guid.Empty);
					}
					else 
					{
                        if (PageLayoutTrace.Sw.TraceVerbose)
                            Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]PageLayout dock_Command Delete not allowed: {0}", strdelperm),PageLayoutTrace.Sw.Info);
                        msgError.Text   = LocalizeHelper.Localize("AM_NO_RIGHTS","You have no privileges for this action");
						return;
					}
				}
            }
        }

        /// <summary>
        /// User have move a module-> store the new position
        /// </summary>
        void dock_DockPositionChanged(object sender, DockPositionChangedEventArgs e)
        {
            if (PageLayoutTrace.Sw.TraceVerbose)
            {
                Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]PageLayout dock_DockPositionChanged BEG sender : {0}, DockZoneID: {1}, Index: {2}", 
                    sender, ((RadDock)sender).DockZoneID,((RadDock)sender).Index), PageLayoutTrace.Sw.Info);
                Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]PageLayout dock_DockPositionChanged new args DockZoneID: {0}, Index: {1}", e.DockZoneID, e.Index), PageLayoutTrace.Sw.Info);
            }
            SaveOrder((RadDock)sender,e);
            if (PageLayoutTrace.Sw.TraceVerbose)
                Trace2.WriteLine( "[V]PageLayout dock_DockPositionChanged END.",PageLayoutTrace.Sw.Info);
        }

        void SaveOrder(RadDock dock, DockPositionChangedEventArgs e)
        {
            if (PageLayoutTrace.Sw.TraceVerbose)
                Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]PageLayout SaveOrder BEG DockZoneID: {0}.",e.DockZoneID),PageLayoutTrace.Sw.Info);
            string pane         =   strContentPane;
            if ( e.DockZoneID == RadDockZone1.ClientID )
                pane            =   strLeftPane;
            else if ( e.DockZoneID == RadDockZone2.ClientID )
                pane            =   strContentPane;
            else if ( e.DockZoneID == RadDockZone3.ClientID )
                pane            =   strRightPane;
            try
            {
                if (PageLayoutTrace.Sw.TraceVerbose)
                    Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]PageLayout SaveOrder ID: {0}, Index: {1}, Pane: {2}", dock.UniqueName,e.Index, pane),PageLayoutTrace.Sw.Info);
                modDB.UpdateModuleOrder(int.Parse(dock.UniqueName),e.Index, pane);
            }
            catch (Exception exp)
            {
                if (PageLayoutTrace.Sw.TraceError)
                    Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[E]PageLayout SaveOrder UniqueName: {0), ex: {1}", dock.UniqueName, exp),PageLayoutTrace.Sw.Info);
                throw;
            }
            if (PageLayoutTrace.Sw.TraceVerbose)
                Trace2.WriteLine( "[V]PageLayout SaveOrder END.",PageLayoutTrace.Sw.Info);
        }

        /// <summary>
        /// Called by DockLayout just after Init
        /// </summary>
        protected void RadDockLayout1_LoadDockLayout(object sender, DockLayoutEventArgs e)
		{
            bool alreadySaved                   =   (CurrentDockStates != null );
            if (PageLayoutTrace.Sw.TraceVerbose)
                Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]PageLayout RadDockLayout1_LoadDockLayout BEG sender : {0}, CurrentDockStates.Count: {1}, e.Positions: {2}", 
                    sender,( alreadySaved ) ? CurrentDockStates.Count:0,e.Positions.Count),PageLayoutTrace.Sw.Info);
            //Populate the event args with the state information. The RadDockLayout control
			// will automatically move the docks according that information.
            if ( alreadySaved )
			    foreach (DockState state in CurrentDockStates)
			    {
                    if (PageLayoutTrace.Sw.TraceVerbose)
                        Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]PageLayout RadDockLayout1_LoadDockLayout DockZoneID: {0}, Index: {1}, UniqueName: [{2}]", 
                            state.DockZoneID,state.Index,state.UniqueName),PageLayoutTrace.Sw.Info);
				    e.Positions[state.UniqueName]   =   state.DockZoneID;
				    e.Indices[state.UniqueName]     =   state.Index;
			    }
            if (PageLayoutTrace.Sw.TraceVerbose)
                Trace2.WriteLine( "[V]PageLayout RadDockLayout1_LoadDockLayout END.",PageLayoutTrace.Sw.Info);
		}

        /// <summary>
        /// Called by DockLayout just after PreRender
        /// </summary>
        protected void RadDockLayout1_SaveDockLayout(object sender, DockLayoutEventArgs e)
		{
            bool alreadySaved                   =   ( CurrentDockStates != null );
            if (PageLayoutTrace.Sw.TraceVerbose)
                Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]PageLayout RadDockLayout1_SaveDockLayout BEG sender : {0}, CurrentDockStates.Count: {1}, e.Positions.Count: {2}", 
                    sender,( alreadySaved ) ? CurrentDockStates.Count:0,e.Positions.Count),PageLayoutTrace.Sw.Info);
			//Save the dock state in the session. This will enable us 
			// to recreate the dock in the next Page_Init. 
			List<DockState> lst     =   RadDockLayout1.GetRegisteredDocksState();
            if (PageLayoutTrace.Sw.TraceVerbose)
                Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]PageLayout RadDockLayout1_SaveDockLayout GetRegisteredDocksState Count: {0}", lst.Count),PageLayoutTrace.Sw.Info);
			CurrentDockStates       =   lst;
            if (PageLayoutTrace.Sw.TraceVerbose)
                Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]PageLayout RadDockLayout1_SaveDockLayout END CurrentDockStates.Count: {0}", CurrentDockStates.Count),PageLayoutTrace.Sw.Info);
		}


        private void CreateSaveStateTrigger(RadDock dock,bool registerjava)
        {
            if (PageLayoutTrace.Sw.TraceVerbose)
                Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]PageLayout CreateSaveStateTrigger BEG Command.dock.ID: {0}, registerjava: {1}",
                    dock.ID,registerjava),PageLayoutTrace.Sw.Info);
            // Ensure that the RadDock control will initiate postback
            // when its position changes on the client or any of the commands is clicked.
            // Using the trigger we will "ajaxify" that postback.
            dock.AutoPostBack                       = true;
            dock.CommandsAutoPostBack               = true;
            // we want to be informed of position change as soon as they occur
            dock.DockPositionChanged                += new DockPositionChangedEventHandler(dock_DockPositionChanged);
            if ( registerjava )
                AddAjaxSetting(dock,Panel1);
            if (PageLayoutTrace.Sw.TraceVerbose)
                Trace2.WriteLine( "[V]PageLayout CreateSaveStateTrigger END.",PageLayoutTrace.Sw.Info);
        }


        /// <summary>
        /// Create a Dock either from DB, either from button_click (->AddToLayout false)
        /// </summary>
        protected void AddNewDock(ModuleItem m,RadDockZone zn,bool AddToLayout )
		{
            if (PageLayoutTrace.Sw.TraceVerbose)
                Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]PageLayout AddNewDock BEG module ID: {0}, AddToLayout: {1}, zone.ClientID: {2}", m.ID,AddToLayout,zn.ClientID),PageLayoutTrace.Sw.Info);
			RadDock dock            =   CreateRadDock(m);
            if ( AddToLayout )
            {
                RadDockLayout1.Controls.Add(dock);
                dock.Dock(zn);
                CreateSaveStateTrigger(dock,false); // AjaxManager is not defined
            }
            else // new dock added by button Add
            {
                //In order to optimize the execution speed we are adding the dock to a 
                // hidden update panel and then register a script which will move it
                // to RadDockZone1 after the AJAX request completes. If you want to 
                // dock the control in other zone, modify the script according your needs.
                Panel2.Controls.Add(dock);
        
                string scrpt = string.Format(@"function _addDock() {{
                Sys.Application.remove_load(_addDock);
                $find('{1}').dock($find('{0}'));
                $find('{0}').doPostBack('DockPositionChanged');
            }};
            Sys.Application.add_load(_addDock);", dock.ClientID, zn.ClientID);
                if (PageLayoutTrace.Sw.TraceVerbose)
                    Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]PageLayout AddNewDock script:\r\n {0}", scrpt),PageLayoutTrace.Sw.Info);
                ScriptManager.RegisterStartupScript(dock, GetType(), "AddDock", scrpt, true);
			    //  Right now the RadDock control is not docked. When we try to save its state
			    // later, the DockZoneID will be empty. To workaround this problem we will 
			    // set the AutoPostBack property of the RadDock control to true and will 
			    // CHANGED: attach an AsyncPostBackTrigger for the DockPositionChanged client-side event. 
                // ajaxify each dock.
                // This will initiate second AJAX request in order to save the state
			    // after the dock will be docked in its new RadDockZone.
			    CreateSaveStateTrigger(dock,true);
            }
		}

        private RadDock CreateRadDockFromState(DockState state)
        {
            if (PageLayoutTrace.Sw.TraceVerbose)
                Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]PageLayout CreateRadDockFromState BEG state.Title: {0}, state.DockZoneID: {1}, UniqueName: {2}", state.Title,state.DockZoneID,state.UniqueName),PageLayoutTrace.Sw.Info);
            RadDock dock            =   new RadDock();
            dock.DockMode           =   DockMode.Docked;
            dock.ID                 =   string.Format("RadDock_{0}", state.UniqueName);
            dock.CssClass           =   "DockZ" ;
            dock.ApplyState(state);
            if (PageLayoutTrace.Sw.TraceVerbose)
                Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]PageLayout CreateRadDockFromState UniqueName: {0}, ID: {1}", dock.UniqueName,dock.ID),PageLayoutTrace.Sw.Info);
            //We will just add the RadDock control to the RadDockLayout.
            // You could use any other control for that purpose, just ensure
            // that it is inside the RadDockLayout control.
            // The RadDockLayout control will automatically move the RadDock
            // controls to their corresponding zone in the LoadDockLayout
            // event (see below).
            RadDockLayout1.Controls.Add(dock);
            AddCommands(dock);
            InsertDockContent(dock);
            if (PageLayoutTrace.Sw.TraceVerbose)
                Trace2.WriteLine( "[V]PageLayout CreateRadDockFromState END.",PageLayoutTrace.Sw.Info);
            return dock;
        }

        private RadDock CreateRadDock(ModuleItem m)
        {
            if (PageLayoutTrace.Sw.TraceVerbose)
                Trace2.WriteLine( "[V]PageLayout CreateRadDock BEG.",PageLayoutTrace.Sw.Info);
            RadDock dock            =   new RadDock();
            dock.DockMode           =   DockMode.Docked;
            dock.UniqueName         =   m.ID.ToString();
            dock.Tag                =   m.ModuleGuid.ToString();
            dock.ID                 =   string.Format("RadDock_{0}", dock.UniqueName);
            dock.CssClass           =   "DockZ" ;
            dock.Title              =   m.Title;
            dock.Text               =   string.Format("Module {0}", m.Title);
            //dock.Width              =   RadDockZone1.Width;
            dock.Skin               =   RadDockLayout1.Skin;
            if (PageLayoutTrace.Sw.TraceVerbose)
                Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]PageLayout CreateRadDock UniqueName: [{0}], ID: {1}", dock.UniqueName,dock.ID),PageLayoutTrace.Sw.Info);
            AddCommands(dock);
            InsertDockContent(dock);
            if (PageLayoutTrace.Sw.TraceVerbose)
                Trace2.WriteLine( "[V]PageLayout CreateRadDock END.",PageLayoutTrace.Sw.Info);
            return dock;
        }

        /// <summary>
        /// Add command buttons to the newly created Dock
        /// </summary>
        void AddCommands(RadDock dock)
        {
            if (PageLayoutTrace.Sw.TraceVerbose)
                Trace2.WriteLine( "[V]PageLayout AddCommands BEG.",PageLayoutTrace.Sw.Info);
            dock.Commands.Add(new DockCloseCommand());// -> used to delete
            dock.Commands.Add(new DockExpandCollapseCommand());

            DockCommand command     =   new DockCommand();
            command.AutoPostBack    =   true;
            command.Name            =   "Edit";
            command.Text            =   LocalizeHelper.Localize("EDIT","Edit");
            dock.Commands.Add(command);
            dock.Command            +=  new DockCommandEventHandler(dock_Command);
            if (PageLayoutTrace.Sw.TraceVerbose)
                Trace2.WriteLine( "[V]PageLayout AddCommands END.",PageLayoutTrace.Sw.Info);
        }

        /// <summary>
        /// Fill the values inside the new dock
        /// </summary>
        void InsertDockContent(RadDock dock)
        {
            if (PageLayoutTrace.Sw.TraceVerbose)
                Trace2.WriteLine( "[V]PageLayout InsertDockContent BEG.",PageLayoutTrace.Sw.Info);
            HtmlGenericControl  pnl =   new HtmlGenericControl(StStr.Div);
            pnl.ID                  =   string.Format("pnl_{0}",dock.UniqueName);
            RadComboBox Ddl         =   new RadComboBox();
            Ddl.Style.Add(HtmlTextWriterStyle.Width,"100%");
            Ddl.ID                  =   string.Format("ddl_{0}_Perm",dock.UniqueName);
            
            string vPerm            =   PortalSecurity.GetViewPermissions(int.Parse(dock.UniqueName));
            bool SelAllUsers        =   ( vPerm.IndexOf(DBAllUser) > -1  );
            RadComboBoxItem lit     =   new RadComboBoxItem(CRMAllUsers,DBAllUser);
            if ( SelAllUsers )
                lit.Selected        =   true;
            Ddl.Items.Add(lit);
            lit                     =   new RadComboBoxItem(CRMAdmin,DBAdmin);
            if ( !SelAllUsers  )
                lit.Selected        =   true;
            Ddl.Items.Add(lit);
            Ddl.AutoPostBack        =   true;
            Ddl.SelectedIndexChanged +=new RadComboBoxSelectedIndexChangedEventHandler(Ddl_SelectedIndexChanged);
            pnl.Controls.Add(Ddl);
            dock.ContentContainer.Controls.Add(pnl);
            if (PageLayoutTrace.Sw.TraceVerbose)
                Trace2.WriteLine( "[V]PageLayout InsertDockContent END.",PageLayoutTrace.Sw.Info);
        }

        /// <summary>
        /// Called to create dock from the existing modules list in DB
        /// </summary>
        protected void CreateRadDockList(ArrayList lst,RadDockZone zn)
        {
            if (PageLayoutTrace.Sw.TraceVerbose)
                Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]PageLayout CreateRadDockList BEG lst.Count: {0}", lst.Count),PageLayoutTrace.Sw.Info);
            foreach (ModuleItem it in lst)
            {
                if (PageLayoutTrace.Sw.TraceVerbose)
                    Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]PageLayout CreateRadDockList module ID: {0}", it.ID),PageLayoutTrace.Sw.Info);
                AddNewDock(it,zn,true);
            }
            if (PageLayoutTrace.Sw.TraceVerbose)
                Trace2.WriteLine("[V]PageLayout CreateRadDockList END.",PageLayoutTrace.Sw.Info);
        }

        /// <summary>
        /// Called from OnInit to create docking structure
        /// </summary>
        void InitDocks()
        {
            if (PageLayoutTrace.Sw.TraceVerbose)
                Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]PageLayout InitDocks BEG IsPostBack: {0}, IsInAsyncPostBack: {1}",IsPostBack,IsInAsyncPostBack),PageLayoutTrace.Sw.Info);
            if (IsPostBack && SessionDataOk )
            {
                int nb              =  ( CurrentDockStates == null) ? 0:CurrentDockStates.Count; 
                if (PageLayoutTrace.Sw.TraceVerbose)
                    Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]PageLayout InitDocks CurrentDockStates.Count: {0}",nb),PageLayoutTrace.Sw.Info);
                for (int i = 0; i < nb ; i++)
                {
                    DockState dst   =   _currentDockStates[i];
                    if (PageLayoutTrace.Sw.TraceVerbose)
                        Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]PageLayout InitDocks CurrentDockStates[{0}] dst.DockZoneID: {1}, Index: {2}, UniqueName: {3}, Closed: {4}",
                        new object[]{i,dst.DockZoneID,dst.Index,dst.UniqueName,dst.Closed}),PageLayoutTrace.Sw.Info);
                    if ( !dst.Closed )
                    {
                        RadDock dock =  CreateRadDockFromState(dst);
                        CreateSaveStateTrigger(dock,false); // AjaxManager is not here
                    }
                }
            }
            else
            {
                ClearSessionData();
                if (PageLayoutTrace.Sw.TraceVerbose && (IsPostBack && SessionDataOk ) )
                    Trace2.WriteLine("[V]PageLayout InitDocks Lost Session reloading",PageLayoutTrace.Sw.Info);
                // Populate Right Hand Module Data
                ArrayList rightList     = GetModules(strRightPane);
                if ( rightList.Count > 0 )
                {
                    CreateRadDockList(rightList, RadDockZone3);
                    SetSecurityAccess(rightList);
                }

                // Populate Content Pane Module Data
                ArrayList contentList   = GetModules(strContentPane);
                if ( contentList.Count > 0 )
                {
                    CreateRadDockList(contentList, RadDockZone2);
                    SetSecurityAccess(contentList);
                }

                // Populate Left Hand Pane Module Data
                ArrayList leftList      = GetModules(strLeftPane);
                if (leftList.Count > 0)
                {
                    CreateRadDockList(leftList, RadDockZone1);
                    SetSecurityAccess(leftList);
                }
            }
            if (PageLayoutTrace.Sw.TraceVerbose)
                Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]PageLayout InitDocks END CurrentDockStates.Count: {0}",(CurrentDockStates == null) ? 0:CurrentDockStates.Count),PageLayoutTrace.Sw.Info);
        }

		/// <summary>
		/// The GetModules helper method is used to get the modules
		/// for a single pane within the tab
		/// </summary>
		private ArrayList GetModules(string pane) 
		{
            if (PageLayoutTrace.Sw.TraceVerbose)
                Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]PageLayout GetModules BEG Pane:[{0}]",pane),PageLayoutTrace.Sw.Info);
			ArrayList paneModules       =   new ArrayList();
            string strPane              =   pane.ToLower(CultureInfo.InvariantCulture);
			foreach (ModuleConfiguration _module in portalSettings.ActivePageSettings.Modules) 
			{
                if (PageLayoutTrace.Sw.TraceVerbose)
                    Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]PageLayout GetModules _module.PaneName:[{0}], _module.PageID: {1}",_module.PaneName,_module.PageID),PageLayoutTrace.Sw.Info);
				if ( _module.PaneName.ToLower(CultureInfo.InvariantCulture) == strPane && portalSettings.ActivePageSettings.PageID == _module.PageID )
				{
                    if (PageLayoutTrace.Sw.TraceVerbose)
                        Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]PageLayout GetModules Added Title:[{0}], ModuleID: {1}",_module.ModuleTitle,_module.ModuleID),PageLayoutTrace.Sw.Info);
					ModuleItem m        =   new ModuleItem();
					m.Title             =   _module.ModuleTitle;
					m.ID                =   _module.ModuleID;
					m.ModuleDefID       =   _module.ModuleDefID;
					m.Order             =   _module.ModuleOrder;
                    m.ModuleGuid        =   _module.GuidID;
					paneModules.Add(m);
				}
			}
            if (PageLayoutTrace.Sw.TraceVerbose)
                Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]PageLayout GetModules END Pane:[{0}], Count: {1}",pane,paneModules.Count),PageLayoutTrace.Sw.Info);
			return paneModules;
		}

		/// <summary>
		/// The OrderModules helper method is used to reset the display
		/// order for modules within a pane
		/// </summary>
		private void OrderModules (ArrayList list) 
		{
			int i				=   1;
			// sort the arraylist
			list.Sort();
			// renumber the order
			foreach (ModuleItem m in list) 
			{
				// number the items 1, 3, 5, etc. to provide an empty order
				// number when moving items up and down in the list.
				m.Order			=   i;
				i				+=  2;
			}
		}
        #endregion dock methods


		#region main Page Overrides

#if DEBUG

        protected override object SaveViewState()
        {
            if ( PageLayoutTrace.Sw.TraceVerbose )
                Trace2.WriteLine( "[V]PageLayout SaveViewState BEG.",PageLayoutTrace.Sw.Info);
            object o    = base.SaveViewState();
            if ( PageLayoutTrace.Sw.TraceVerbose )
                Trace2.WriteLine( "[V]PageLayout SaveViewState END.",PageLayoutTrace.Sw.Info);
            return o;
        }
        protected override void LoadViewState(object savedState)
        {
            if ( PageTraceSwitch.Sw.TraceVerbose )
                Trace2.WriteLine( "[V]PageLayout LoadViewState BEG.",PageTraceSwitch.Sw.Info);
            base.LoadViewState(savedState);
            if ( PageTraceSwitch.Sw.TraceVerbose )
                Trace2.WriteLine( "[V]PageLayout LoadViewState END.",PageTraceSwitch.Sw.Info);
        }

        protected override void OnPreRenderComplete(EventArgs e)
        {
            if ( PageTraceSwitch.Sw.TraceVerbose )
                Trace2.WriteLine( "[V]PageLayout OnPreRenderComplete BEG.",PageTraceSwitch.Sw.Info);
            base.OnPreRenderComplete(e);
            if ( PageTraceSwitch.Sw.TraceVerbose )
                Trace2.WriteLine("[V]PageLayout OnPreRenderComplete END.",PageTraceSwitch.Sw.Info);
        }
        
        protected override void OnPreRender(EventArgs e)
        {
            if (PageTraceSwitch.Sw.TraceVerbose)
                Trace2.WriteLine( "[V]PageLayout OnPreRender BEG.",PageTraceSwitch.Sw.Info);

            base.OnPreRender(e);
            if (PageTraceSwitch.Sw.TraceVerbose)
                Trace2.WriteLine( "[V]PageLayout OnPreRender END.",PageTraceSwitch.Sw.Info);
        }

#endif

        protected override void OnPreInit(EventArgs e)
        {
            if (PageTraceSwitch.Sw.TraceVerbose || PageLayoutTrace.Sw.TraceVerbose)
                Trace2.WriteLine( "[V]PageLayout OnPreInit BEG.",(PageTraceSwitch.Sw.TraceVerbose)? PageTraceSwitch.Sw.Info: PageLayoutTrace.Sw.Info);
            MasterPage pg         =   Master; // Bug asp.net : with masterpage ctrls ar not created if master not called !!!
            previewBtn.SkinID     =   "Preview_" + Helpers.LocalizeHelper.GetCurrentNeutralCultureName();
            base.OnPreInit(e);
            if (PageTraceSwitch.Sw.TraceVerbose || PageLayoutTrace.Sw.TraceVerbose)
                Trace2.WriteLine( "[V]PageLayout OnPreInit END.",(PageTraceSwitch.Sw.TraceVerbose)? PageTraceSwitch.Sw.Info: PageLayoutTrace.Sw.Info);
        }


		protected override void OnInit(EventArgs e)
		{
            if (PageTraceSwitch.Sw.TraceVerbose || PageLayoutTrace.Sw.TraceVerbose)
                Trace2.WriteLine( "[V]PageLayout OnInit BEG.",(PageTraceSwitch.Sw.TraceVerbose)? PageTraceSwitch.Sw.Info: PageLayoutTrace.Sw.Info);

            InitializeComponent();
            
			base.OnInit(e);
            if (PageTraceSwitch.Sw.TraceVerbose || PageLayoutTrace.Sw.TraceVerbose)
                Trace2.WriteLine( "[V]PageLayout OnInit END.",(PageTraceSwitch.Sw.TraceVerbose)? PageTraceSwitch.Sw.Info: PageLayoutTrace.Sw.Info);
        }

		/// <summary>
		/// Required method for Designer support - do not modify
		/// the contents of this method with the code editor.
		/// </summary>
		private void InitializeComponent() 
		{    
            if (PageTraceSwitch.Sw.TraceVerbose)
                Trace2.WriteLine("[V]PageLayout InitializeComponent BEG.",PageTraceSwitch.Sw.Info);
			//local change with autopostback
            tabName.TextChanged                 +=  new EventHandler(PageSettings_Change);   
            tabName.AutoPostBack                =   true;
			authRoles.SelectedIndexChanged      +=  new EventHandler(PageSettings_Change);   
            authRoles.AutoPostBack              =   true;

            ClbFlags.AutoPostBack               =   true;
            ClbFlags.TextChanged                +=  new EventHandler(ClbFlags_TextChanged);

            DDLPageImage.SelectedIndexChanged   +=  new RadComboBoxSelectedIndexChangedEventHandler(DDLPageImage_SelectedIndexChanged);
            DDLPageImage.AutoPostBack           =   true;

            parentPage.SelectedIndexChanged     +=  new RadComboBoxSelectedIndexChangedEventHandler(parentPage_SelectedIndexChanged);
            parentPage.AutoPostBack             =   true;
            TbLWidth.TextChanged                +=  new EventHandler(TbWidth_TextChanged);
            TbCWidth.TextChanged                +=  new EventHandler(TbWidth_TextChanged);
            TbRWidth.TextChanged                +=  new EventHandler(TbWidth_TextChanged);


            // internal: adding one module
            AddModuleBtn.Click                  +=  new ImageClickEventHandler(AddModuleBtn_Click);   
            // internal update of settings
            EditTable.UpdateControl             +=   new UpdateControlEventHandler(EditTable_UpdateControl);   
			
            // install limitations for display pages from the PortalPagesManager calling Module 
            parentPage.IncludeAdmin             =   moduleSettingsDic[AStr.showAdmin].ToBool();
            if ( PageLayoutTrace.Sw.TraceVerbose)
                Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]PageLayout InitializeComponent InludeAdmin: {0}.",parentPage.IncludeAdmin),PageLayoutTrace.Sw.Info);
            parentPage.SkipList                 =   moduleSettingsDic[AStr.skipList].Value;
            
            moduleType.IncludeAdmin             =   moduleSettingsDic[AStr.showAdmin].ToBool();
            moduleType.SkipList                 =   moduleSettingsDic[AStr.skipModulesList].Value;
            

            RadDockLayout1.SaveDockLayout       +=  new DockLayoutEventHandler(RadDockLayout1_SaveDockLayout);
            RadDockLayout1.LoadDockLayout       +=  new DockLayoutEventHandler(RadDockLayout1_LoadDockLayout);

            Load                                +=  new EventHandler(Page_Load);
            Update                              +=  new PageEventHandler(PageLayout_Update);
            Cancel                              +=  new EventHandler(PageLayout_Cancel);

#if DEBUG
            ScriptManager scm   =  ScriptManager.GetCurrent(Page);
            scm.PreRender += new EventHandler(scm_PreRender);

#endif

            InitDocks();
            if (PageTraceSwitch.Sw.TraceVerbose)
                Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]PageLayout InitializeComponent END CurrentDockStates.Count: {0}",(CurrentDockStates == null) ? 0:CurrentDockStates.Count),PageTraceSwitch.Sw.Info);
			}

#if DEBUG

        void scm_PreRender(object sender, EventArgs e)
        {
            if (PageTraceSwitch.Sw.TraceVerbose)
                Trace2.WriteLine( "[V]PageLayout scm_PreRender CALLED.",PageTraceSwitch.Sw.Info);
        }
#endif
        protected override System.Web.UI.WebControls.PlaceHolder placeHolderForButtons
		{
			get
			{ return PlaceHolderButtons; }
			set { }
		}

        protected override System.Web.UI.WebControls.PlaceHolder placeHolderForButtons2
		{
			get
			{ return PlaceHolderButtons2; }
			set { }
		}
		#endregion

	}
}
